package org.xx.armory.db.impl;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xx.armory.db.DbException;
import org.xx.armory.db.Parameter;
import org.xx.armory.db.ParameterType;
import org.xx.armory.db.Transaction;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.SQLException;

import static java.sql.Types.REF_CURSOR;
import static org.xx.armory.commons.Validators.greaterThanOrEqual;
import static org.xx.armory.commons.Validators.notNull;

/**
 * @author Haart
 */
final class DerbySession
        extends AbstractSession {
    private final Logger logger = LoggerFactory.getLogger(DerbySession.class);

    /**
     * 构造{@code DerbySession}对象。
     *
     * @param transaction
     *         当前会话关联的事务。
     * @throws IllegalArgumentException
     *         如果参数{@code transaction}是{@code null}。
     */
    public DerbySession(Transaction transaction) {
        super(transaction);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected final void addParameter(
            PreparedStatement statement,
            int index,
            Parameter parameter
    )
            throws SQLException {
        notNull(statement, "stmt");
        greaterThanOrEqual(index, "index", 1);
        notNull(parameter, "parameter");

        final ParameterType pType = parameter.getParameterType();
        final int sqlType = toSqlType(pType);

        // 游标只能作为传出参数。
        if (sqlType == REF_CURSOR) {
            if (statement instanceof CallableStatement) {
                try {
                    ((CallableStatement) statement).registerOutParameter(index, REF_CURSOR);
                } catch (SQLException ex) {
                    throw new DbException(ex);
                }
            } else {
                logger.warn("statement does not support out parameter[{}]", index);
            }
        } else {
            super.addParameter(statement, index, parameter);
        }
    }
}
